package la.iok.hzsvn.lewin.movie.cloud.service;

import la.iok.hzsvn.lewin.movie.cloud.entity.User;
import la.iok.hzsvn.lewin.movie.cloud.model.*;
import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.lewin.movie.core.model.SimpleUser;
import la.iok.hzsvn.lewin.movie.core.model.UserVo;
import la.iok.hzsvn.lewin.mybatis.model.PageVo;
import la.iok.hzsvn.lewin.mybatis.service.BaseService;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.Nullable;

import java.util.List;

public interface UserService extends BaseService<User,Long> {
    /**
     * 保存用户
     * @param token 操作用户,可能为null
     * @param userParam 用户信息
     * @return 新用户id
     */
    Long save(@Nullable Token token, @NotNull UserParam userParam);

    /**
     * 保存用户
     * @param userParam 用户信息
     * @return 新用户id
     */
    Long save(@NotNull UserParam userParam);
    /**
     * 登录的时候注册。目前就玩家在登录的时候如果用户不存在需要注册
     * @param param 登录信息
     * @return 新注册用户id
     */
    Long save(@NotNull UserLoginParam param);
    /**
     * 扫描二维码保存用户
     * @param userParam 用户信息
     * @return 新用户id
     */
    Long qrCodeSave(@NotNull UserParam userParam);

    /**
     * 通过微信认证进行用户注册。此时注册的都是玩家
     * @return 新保存用户的id
     */
    Long wxSave(String phoneNumber);

    /**
     * 通过手机号查找用户
     * @param phoneNumber 手机号
     * @return 用户
     */
    @Nullable
    User select(@Nullable String phoneNumber);

    /**
     * 用户转vo对象
     * @param user 实体对象
     * @return vo对象
     */
    @Nullable
    UserVo po2vo(@Nullable User user);

    /**
     * 分页查询用户列表
     * @param page 页号
     * @param limit 分页大小
     * @param token 操作用户,根据权限查询
     * @param orgUnitId 组织id，如果非空,则只查询此组织的用户
     * @param phoneNumber 手机号,模糊匹配
     * @return 用户列表
     */
    PageVo<UserVo> page(int page, int limit, Token token, Long orgUnitId, String phoneNumber);

    /**
     * 修改用户信息。管理人员修改他管理的用户信息
     * @param token 操作用户
     * @param id 要修改的用户id
     * @param user 用户信息
     */
    void modify(@NotNull Token token, @NotNull Long id, @NotNull UserModifyParam user);

    /**
     * 重置用户密码
     * @param token 操作用户
     * @param id 要重置密码的用户id
     */
    void resetPwd(@NotNull Token token, @NotNull Long id);

    /**
     * 修改当前组织
     * @param token 操作用户
     * @param orgUnitId 组织id
     */
    void current(@NotNull Token token, @Nullable Long orgUnitId);

    /**
     * 邀请用户加入本组织
     * @param token 操作用户
     * @param phoneNumber 邀请用户的手机号
     * @param role 邀请用户担任的角色
     */
    void invite(@NotNull Token token, @Nullable String phoneNumber, @Nullable String role);

    /**
     * 从组织移除用户的一个角色
     * @param token 操作用户
     * @param userRoleId 用户角色id
     */
    void remove(@NotNull Token token,@Nullable Long userRoleId);

    /**
     * 用户修改自己的账号信息
     * @param token 操作用户
     * @param account 账号信息
     */
    void modifyAccount(@NotNull Token token, @NotNull AccountModifyParam account);

    /**
     * 用户修改自己的密码
     * @param token 操作用户
     * @param param 密码修改信息
     */
    void modifyPassword(@NotNull Token token, @NotNull PasswordModifyParam param);

    void modifyPassword(@NotNull ForgotSetPasswordParam param);

    /**
     * 用户登录获取令牌
     * @param param 登录信息
     * @return 令牌信息
     */
    TokenInfo token(UserLoginParam param);

    /**
     * 当天活跃用户数统计
     * @return 用户数统计
     */
    List<AccessCount> todayActiveUser();

    /**
     * 修改操作用户自己的昵称
     * @param token 操作用户
     * @param nickname 昵称
     */
    void nickname(@NotNull Token token, @Nullable String nickname,@Nullable int gender);

    /**
     * 禁止用户。被禁止的用户将不能再登录，并且账号被保留在系统中
     * @param token 操作用户，只能是Admin权限用户
     * @param id 被禁止的用户id
     */
    void disable(@NotNull Token token, @Nullable Long id);

    /**
     * 重新启用用户
     * @param token 操作用户，只能是Admin权限用户
     * @param id 被启用用户id
     */
    void enable(@NotNull Token token, @Nullable Long id);

    /**
     * 根据id查询多个用户.只包含用户表信息,不包含关联信息
     * @param ids 用户id数组
     * @return 用户列表
     */
    @NotNull
    @NotNullElement
    List<SimpleUser> users(@Nullable Long[] ids);

    User selectUser(Long UserId);
}
